<?php

use models\Business\Address;
use models\Business\Alibaba;
use models\Business\AlibabaProduct;
use models\Business\Booking;
use models\Business\Order;
use models\Business\RefundInfo;
use models\Business\Album;
use models\Exception\Business\OrderException;
use models\Exception\Business\RefundinfoException;
use models\Business\Member;
use Yaf\Registry;
use models\Exception\AbstractException;


class OrderController extends ApiBaseController
{
    /**
     * @SWG\Get(
     *     path="/v3/order/list",
     *     tags={"订单模块"},
     *     summary="获取1688订单列表数据接口",
     *     description="
     * page 必须参数 页码
     * page_size 必须参数 每页显示条数
     * sort 必须参数 排序方式 可选值:desc降序、asc生序
     * order 必须参数 排序字段 可选值 created_at|updated_at排序
     * stats 必须参数 状态 可选值:0待支付,1为待发货,2为待收货,3为确认收货，10进行中,11未拼中订单(拼团失败),99为待支付、待发货、待收货的全部订单
     *       100为退款与退货全部，101为退货中，102为处理中，103为已退货，104退款中，105已退款，106退款失败，107退货失败
     * (失效，改为stats 11)failure_stats 非必须参数 未拼中订单 值：toBeContinued，并且stats为99",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值 该参数在获取商品详情页的'他们正在拼'时才允许不传，其他时候必须",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="签名",
     *          in="query",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="200",
     *         description="请求成功",
     *         @SWG\Schema(type="object", ref="#/definitions/orderListData")
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function orderAction()
    {

        $parameters = Registry::get('parameters');

        // 获取指定商品的其他用户正在进行的拼团
        if (isset($parameters['others']) && $parameters['others'] == 1 &&
            isset($parameters['product_id']) && !empty($parameters['product_id'])) {
            $order_list = Booking::getBookingList(['product_id' => $parameters['product_id'], 'stats' => 1,
                'page' => $parameters['page'], 'page_size' => $parameters['page_size'],
                'start_created_at' => date('Y-m-d H:i:s', time())]);
//                'start_expired_at' => date('Y-m-d H:i:s', time())]);
        } else {
            $parameters['member_id'] = Registry::get('jwt_info')->id;
            if (is_null($parameters['member_id']))
                throw new AbstractException(AbstractException::LOGIN_FIRST, AbstractException::LOGIN_FIRST_NO);
            //未付款
            if ($parameters['stats'] == 0||$parameters['stats']==11||$parameters['stats']==10) {
                //已支付为拼团进行中
                if($parameters['stats']==10) {
                    $parameters['stats'] = [1,20];
//                    $parameters['start_expired_at'] = date('Y-m-d H:i:s', time());
                    $parameters['start_created_at'] = date('Y-m-d H:is:', time());
                }elseif ($parameters['stats']==11){
                    $parameters['stats'] = 10;
                } else {
                    $parameters['stats'] = 0;
                    $parameters['start_expired_at'] = date('Y-m-d H:i:s', time());
                }
                $order_list = Booking::getBookingList($parameters);
            } else {
                $order_list = Order::getOrderList($parameters);
            }
        }
        // 读取会员头像等相关数据
        $order_list = Member::getMembersByModules($order_list, false);

        return $this->_responseJson($order_list);
    }

    /**
     *
     * @SWG\Get(
     *     path="/v3/order/processing",
     *     tags={"订单模块"},
     *     summary="获取指定商品正在进行的拼团数据",
     *     description="
     * page 必须参数 页码
     * page_size 必须参数 每页显示条数
     * sort 必须参数 排序方式 可选值:desc降序、asc生序
     * order 必须参数 排序字段 可选值 created_at|updated_at排序
     * product_id 非必须参数 当获获取指定商品正在进行的拼团数据必须，反之则获取所有正在进行拼团的数据",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值 该参数在获取商品详情页的'他们正在拼'时才允许不传，其他时候必须",
     *          in="header",
     *          required=false,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="签名",
     *          in="query",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="200",
     *         description="请求成功",
     *         @SWG\Schema(type="object", ref="#/definitions/orderListData")
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function processingAction() {
        $parameters = Registry::get('parameters');
        $param = ['stats' => [1,20], 'page' => $parameters['page'], 'page_size' => $parameters['page_size'],
            'start_created_at' => date('Y-m-d H:i:s', time())];
//                'start_expired_at' => date('Y-m-d H:i:s', time())]);
        if (isset($parameters['product_id']) && !empty($parameters['product_id'])) {
            $param['product_id'] = $parameters['product_id'];
            $order_list = Booking::getBookingList($param);
        } else
            $order_list = Booking::getBookingListByProductId($param);
//        else
//            $order_list = Booking::getBookingListByProductId($param);
//        $order_list = Booking::getBookingList(['product_id' => $parameters['product_id'], 'stats' => 1,
//            'page' => $parameters['page'], 'page_size' => $parameters['page_size'],
//            'start_created_at' => date('Y-m-d H:i:s', time())]);
        // 读取会员头像等相关数据
        $order_list = Member::getMembersByModules($order_list);

        return $this->_responseJson($order_list);
    }

    /**
     * @SWG\Get(
     *     path="/v3/order/{order_sn}/info",
     *     tags={"订单模块"},
     *     summary="获取指定订单的订单详情",
     *     description="
     * timestamp 必须参数 当前时间戳
     *  stats 非必须参数 可选值：1为进行中或待支付 或 为未拼中",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="order_sn",
     *          description="/v3/order/list接口返回的sn字段的值",
     *          in="path",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="加密字符串",
     *          in="query",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="200",
     *         description="请求成功"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function infoAction()
    {
        $parameters     = Registry::get('parameters');

        if($parameters['stats']==1){
            $info=Booking::getBookingBySn($parameters['order_sn']);
            $info['price']= sprintf('%.2f',$info['price']);
        }else{
            $info = Order::getOrderBySn($parameters['order_sn']);
            $info['amount']= sprintf('%.2f',$info['amount']);
            $booking = Booking::getBookingBySn($parameters['order_sn']);
            if(isset($booking['num'])){
                $info['num']=$booking['num'];
            }
        }

        if ($info['member_id'] != Registry::get('jwt_info')->id)
            throw new RefundinfoException(OrderException::ORDER_DENIED, OrderException::ORDER_DENIED_NO);

        if (empty($info)) {
            throw new OrderException(OrderException::ORDER_IS_NOT_EXISTS, OrderException::ORDER_IS_NOT_EXISTS_NO);
        }
        if ($parameters['stats'] == 1) {
            //已支付为拼团进行中
            if($info['stats']==1){
                $info['statsname']='等待拼单结果';
            }elseif($info['stats']==0){
                $info['statsname']='等待买家付款';
            }elseif($info['stats']==10){
                $info['statsname']='未拼中';
            }else{
                throw new OrderException(OrderException::ORDER_IS_NOT_EXISTS, OrderException::ORDER_IS_NOT_EXISTS_NO);
            }
        } else {
            if($info['refund_stats']==3){
                //退款成功 所退金额= 商品价格-服务费+花费运费
                $refund_amount=$info['amount']-$info['service_fee'];
            }elseif ($info['refund_stats']==4){
                //退货成功 所退金额= 商品价格-服务费
                $refund_amount=$info['amount']-$info['service_fee']-$info['fee'];
            }else{
                $refund_amount=0;
            }
            //退款退货信息
            if($info['refund_stats']>0){
                $refundInfo = RefundInfo::getRefundInfoBySn($parameters['order_sn']);
                //卖家拒绝理由
                $info['refuse']= isset($refundInfo['refuse'])?$refundInfo['refuse']:'';
            }
            $info['refund_amount']=sprintf('%.2f',$refund_amount);
            $info['statsname']=Order::getOrderDetailName($info['stats'],$info['refund_stats']);
        }


        $info['address_info'] = Address::getAddress(['id' => $info['address_id']]);
        $products = AlibabaProduct::getProduct(['id' => $info['product_id'], 'from_api' => true]);
        $info['product_info'] =$products['data'][0];
        $result['data']=$info;
        return $this->_responseJson($result);
    }

    /**
     * @SWG\Put(
     *     path="/v3/order/{order_sn}/operate",
     *     tags={"订单模块"},
     *     summary="操作指定订单，对其发起退款、退货、确认收货、撤销退货退款的操作",
     *     description="
     * action 必须参数 refund退款 return退货 confirm确认收货 cancel撤销退货、退款",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="order_sn",
     *          description="/v3/order/list接口返回的sn字段的值",
     *          in="path",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="加密字符串",
     *          in="formData",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="200",
     *         description="请求成功"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function operateAction()
    {
        $parameters = Registry::get('parameters');

        // 判断action的值是否为refund或return
        if (!in_array($parameters['action'], ['refund', 'return', 'confirm', 'cancel'])) {
            // 若不是，则提示用户"非法退款、退货操作"
            throw new OrderException(OrderException::ORDER_OPERATE_FAILURE, OrderException::ORDER_OPERATE_FAILURE_NO);
        }
        if ($parameters['action'] == 'refund') {
            $result = Order::refundOrder($parameters['order_sn']);
        } else if ($parameters['action'] == 'confirm') {
            $result = Order::confirmOrder($parameters['order_sn']);
        } else if ($parameters['action'] == 'cancel') {
            $result = RefundInfo::deleteInfo($parameters);
        } else {
            $result = Order::returnOrder($parameters['order_sn']);
        }
        return $this->_responseJson($result);
    }

    /**
     * @SWG\Put(
     *     path="/v3/order/{order_sn}/orderRefund",
     *     tags={"订单模块"},
     *     summary="提交、修改某个订单的退款退货理由",
     *     description="
     * reason_id 必须参数 退款理由id 为operate返回的理由列表id
     * reason 必须参数 退款理由
     * action 必须参数 refund退款 return退货
     * album 非必须  return退货 上传凭证 图片用‘,’间隔，最多5张
     *     ",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="order_sn",
     *          description="/v3/order/list接口返回的sn字段的值",
     *          in="path",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="加密字符串",
     *          in="formData",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="200",
     *         description="请求成功"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function orderRefundAction()
    {
        $parameters = Registry::get('parameters');
        // 判断action的值是否为refund或return
        if (!in_array($parameters['action'], ['refund', 'return'])) {
            // 若不是，则提示用户"非法退款、退货操作"
            throw new OrderException(OrderException::ORDER_OPERATE_FAILURE, OrderException::ORDER_OPERATE_FAILURE_NO);
        }
        //判断订单状态
        $order = Order::getOrderBySn($parameters['order_sn']);
        if (empty($order) || empty($order['trade_order_sn'])) {
            throw new OrderException(OrderException::ORDER_IS_NOT_EXISTS, OrderException::ORDER_IS_NOT_EXISTS_NO);
        }

        // 判断退货退款信息是否存在，若存在则表明用户是修改已经创建好的退货退款信息；反之则表示用户需要创建退货退款信息
        $refundInfo=RefundInfo::getNewRefundInfo($parameters,$order);
        $refundInfo['count_down']=3*86400*1000;
        // 修改booking的stats为"申请退货"
        Booking::editBooking(['sn' => $parameters['order_sn'], 'stats' => $parameters['action'] == 'refund' ? 4 : 5]);
        // 修改订单状态
        $update_arr = [
            'sn' => $parameters['order_sn'],
            'refund_stats' => $parameters['action'] == 'refund' ? 1 : 2
        ];
        //记入退款退货时间
        if($parameters['action'] == 'refund'){
            $update_arr['refunded_at']=date('Y-m-d H:i:s', time());
        }else{
            $update_arr['returned_at']=date('Y-m-d H:i:s', time());
        }
        Order::editOrder($update_arr);
        //退货允许修改退货信息,如果有退货信息直接返回

        if ($parameters['action']=='return') {
            return $this->_responseJson($refundInfo);
        }

        $msg = '';
        try {
            Order::payOrRefund($order['trade_order_sn'],'refund');
            $msg = '退款申请成功，请等待交易金额退回余额';
        } catch (\Exception $e) {
            if($e->getCode()!=111)
                throw new OrderException($e->getMessage(), $e->getCode());
        }

        if (empty($msg)) {
            //直接执行退款 向1688发起退款
            $msg = Order::refundReturn($refundInfo,$order);

        }
        return $this->_responseJson(new stdClass(), '000', $msg);

       // 具体调用1688退货退款接口的逻辑是：在每个钟头的0分0秒，查询6个钟头前的，refundinfo表中refund_order_id为0，对应的order表记录的refund_stats为1或2的记录，并调用1688接口
       // 跳用1688退货接口的方法：在根目录执行命令行 php public/cli.php request_uri="/common/common/refundReturn"
    }

    /**
     * @SWG\Put(
     *     path="/v3/order/{order_sn}/refund",
     *     tags={"订单模块"},
     *     summary="提交某个退货订单的快递信息",
     *     description="
     * logistics_company_no 必须参数 物流公司编码
     * freight_bill 必须参数 物流公司运单号，请准确填写，否则卖家有权拒绝退款
     * description  非必须参数 发货说明，内容在2-200个字之间
     * album 非必须  快递信息 上传凭证 图片用‘,’间隔，最多可上传 10 张图片 ；单张大小不超过1M；支持jpg、gif、jpeg、png、和bmp格式。
     *     ",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="order_sn",
     *          description="/v3/order/list接口返回的sn字段的值",
     *          in="path",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="加密字符串",
     *          in="formData",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="200",
     *         description="请求成功"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function refundAction()
    {
        $parameters = Registry::get('parameters');
        //判断订单状态
        $order = Order::getOrderBySn($parameters['order_sn']);
        if (empty($order) || empty($order['trade_order_sn']) || $order['refund_stats'] != 7) {
            throw new OrderException(OrderException::ORDER_STATS_ALREADY, OrderException::ORDER_STATS_ALREADY_NO);
        }
        $refundInfo = RefundInfo::getRefundInfoBySn($parameters['order_sn']);
        if(empty($refundInfo)||empty($refundInfo['refund_order_id'])){
            throw new OrderException(RefundinfoException::REFUNDINFO_IS_NOT_EXISTS, RefundinfoException::REFUNDINFO_IS_NOT_EXISTS_NO);

        }
        // 物流公司编码
        $logistics_company_no = $parameters['logistics_company_no'];
        // 运单号
        $freight_bill = $parameters['freight_bill'];
        // 发货说明，内容在2-200个字之间
        $description = $parameters['description'];
        // 凭证图片URLs，uploadRefundVoucher接口返回结果
        // 存在图片，插入图片后将返回结果的id赋值给parameters_arr的album_id键
        if (!empty($parameters['album'])) {
            $current_time = date('Y-m-d H:i:s', time());
            // 生成插入album的数组
            $album_insert_arr = ['type'       => 3, 'album' => $parameters['album'], 'stats' => 1,
                                 'created_at' => $current_time, 'updated_at' => $current_time];
            // 插入数据库 并将返回结果的id赋值给parameters_arr的album_id键
            $album_res = Album::createAlbum($album_insert_arr);

            $parameters['album_id'] = $album_res['id'];
            $vouchers               = explode(',', $parameters['album']);
            // 上传凭证
            $vouchers_arr = Alibaba::tradeUploadRefundVoucher($order['sn'], $vouchers);
        }


        $res = Alibaba::tradeRefundReturnGoods($refundInfo['refund_order_id'], $logistics_company_no, $freight_bill, $description, $vouchers_arr);

        if ($res['success'] == true) {
            //记录物流信息
            $logistics = serialize($parameters);
            $info      = RefundInfo::getRefundInfoBySn($order['sn']);
            $infodata  = ['id' => $info['id'], 'logistics' => $logistics];
            RefundInfo::editInfo($infodata);
            return $this->_responseJson(new stdClass(), '000', '提交成功');
        } else {
            Registry::get('order_log')->err("退货订单的快递信息,sn编号:" . $order['sn'] . ", 原因: " . $res['errorInfo']);
            throw new OrderException(OrderException::ORDER_STATS_ALREADY, OrderException::ORDER_STATS_ALREADY_NO);
        }
        // 注：当1688卖家处理完毕后，在notify/alibaba/orderStatus接口接收1688的推送消息
    }

    /**
     * @SWG\Put(
     *     path="/v3/refundorder/{order_sn}/info",
     *     tags={"订单模块"},
     *     summary="获取某个退货订单详情和卖家信息",
     *     description="
     *
     *     timestamp 必须参数 当前时间戳",
     *     @SWG\Parameter(
     *          name="Authorization",
     *          description="Authorization 登录接口返回的jwt字段的值",
     *          in="header",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="order_sn",
     *          description="/v3/order/list接口返回的sn字段的值",
     *          in="path",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Parameter(
     *          name="secret",
     *          description="加密字符串",
     *          in="formData",
     *          required=true,
     *          type="string"
     *     ),
     *     @SWG\Response(
     *         response="200",
     *         description="请求成功"
     *     ),
     *     @SWG\Response(
     *         response="400",
     *         description="签名不存在或无效签名"
     *     ),
     *     @SWG\Response(
     *         response="401",
     *         description="jwt无效或过期，需要登录"
     *     ),
     *     @SWG\Response(
     *         response="403",
     *         description="无权访问"
     *     ),
     *     @SWG\Response(
     *         response="404",
     *         description="找不到数据"
     *     )
     * )
     */
    public function refundInfoAction()
    {
        $parameters = Registry::get('parameters');

        $refundInfo = RefundInfo::getRefundInfoBySn($parameters['order_sn']);
        if ($refundInfo['member_id'] != Registry::get('jwt_info')->id)
            throw new RefundinfoException(RefundinfoException::REFUNDINFO_SELECT, RefundinfoException::REFUNDINFO_SELECT_NO);

        if (empty($refundInfo)) {
            throw new OrderException(RefundinfoException::REFUNDINFO_IS_NOT_EXISTS, RefundinfoException::REFUNDINFO_IS_NOT_EXISTS_NO);

        }
        $refundInfo=Album::getAlbumByModule($refundInfo);
        //买家发货倒计时6天
        $refundInfo['count_down']=6*86400*1000;
        //撤销时间6小时内
        $catime = strtotime($refundInfo['updated_at'])+6*3600; //日期转换为时间戳
        $refundInfo['expire_at'] = date('Y-m-d H:i:s', $catime); //时间戳又转回日期了
        return $this->_responseJson(['data' => $refundInfo]);
    }

}
